I have long seen suggestions for a "more advanced LMC" with binary and more features. After discussion with a lecturer at the University of Oslo, who was looking for the simplicity of the LMC but the ability to set more complex exercises, I have altered the RISC simulator to be LMC compatible.
When released, this will allow LMC programs to be run on a 16 bit simulator with ability to display signed, unsigned, hex or binary representations of memory. It has a larger output area, a count of instructions executed (so you can compare solutions) and highlighting of the assembly language instruction currently being executed.
It is currently in final testing, but if you would like to join in the testing, you can read what it does at www.peterhigginson.co.uk/RISC/better_lmc.html and that document contains a link to the test version of the new simulator.
V1.1 Changes Close input memory/PC location when lose focus (mouse clicked elsewhere). Any valid input is accepted. Add default speed options. Allow TAB to go to next memory location. (11/12/2014)
V1.3 Changes Prevent backspace (when not editing) doing "browser back". In the assembly area, add a cancel button and make the buttons more obvious. (28/2/2015)
V1.4 Changes I have added some scaling to expand to larger screens and I have also rate limited requests to load the software. V1.4a fixed a bug handing bad input to the PC. (16/1/2023)
Help in Turkish I am grateful to Turgut Guneysu for his translation of the help file into Turkish. LMC Yardim Notlari.
The LMC is really not a good model of a modern computer CPU and I have made three versions of something better. The first is a RISC Simulator with a multi-register CPU and an ARM-like instruction set www.peterhigginson.co.uk/RISC. It is a 16-bit CPU with a much larger instruction set and a stack.
The second is a simulation that implements "only" the instructions that the AQA exam board uses in their examinations. There are vague areas in the AQA specification and I have had to make choices - such as a 32 bit word size and using ARM instruction encodings. The only serious extension is the inclusion of an indirect addressing mode. You can find it at www.peterhigginson.co.uk/AQA. There is also a Snake game project for this simulation written by Richard Pawson.
In 2020, I released ARMlite in conjunction with a new A-level textbook written by Richard Pawson. ARMlite has more memory (1 MB), a cleaner interface, an extended instruction set (interrupts, subroutines, a stack etc.) and is much higher performance (1-10 million instructions per second, depending on your browser and computer). Assembly Language Programming by Richard Pawson with Peter Higginson, is a textbook written specifically for teaching A-level. This is part of a series of books called "Computer Science from the Metal Up" by Richard which you can find on his web site using this link. Free download of the student versions is available. You can also email Richard (rpawson at metalup.org).
The Little Man Computer (LMC) is an instructional model of a computer, created by Dr. Stuart Madnick in 1965. It models the architecture of a simple computer and has all the basic features. See en.wikipedia.org/wiki/Little_man_computer for more information.
The original concept was that inside the CPU is a tiny man who runs around executing instructions encoded in a list. Inside the CPU there are:
The Program Counter holds only 2 digits (0 to 99) and the Accumulator holds 3 digits and a sign (-999 to 999). The Output area holds a certain amount of information in two columns and then scrolls (and old information disappears).
When an instruction is read from memory the top digit is used to decide what to do. To help us write programs more easily each instruction type is given a name which the ASSEMBLE function converts to the corresponding code. The bottom two digits are used as an address associated with the instruction. The instructions are:
Code | Name | Description | ||||
0 | HLT | Stop (Little Man has a rest). | ||||
1 | ADD | Add the contents of the memory address to the Accumulator | ||||
2 | SUB | Subtract the contents of the memory address from the Accumulator | ||||
3 | STA or STO | Store the value in the Accumulator in the memory address given. | ||||
4 | This code is unused and gives an error. | |||||
5 | LDA | Load the Accumulator with the contents of the memory address given | ||||
6 | BRA | Branch - use the address given as the address of the next instruction | ||||
7 | BRZ | Branch to the address given if the Accumulator is zero | ||||
8 | BRP | Branch to the address given if the Accumulator is zero or positive | ||||
9 | INP or OUT | Input or Output. Take from Input if address is 1, copy to Output if address is 2. | ||||
9 | OTC | Output accumulator as a character if address is 22. (Non-standard instruction) | ||||
DAT | Used to indicate a location that contains data. |
Note that the LMC computer cannot tell whether memory locations contain instructions or data. Most modern computers can segment their memory but there has to be a way for the output from one program the become the instructions of another. DAT is a fake instruction to tell the assembler that this location contains data.
This implementation allows you to output both numbers (OUT) and characters (OTC). On a real computer you would only have the OTC instruction and the program would have to convert numbers to characters before printing. (Standard routines are provided.) The same is true for input but we have provided INP to input numbers for simplicity.
The assembler also allows us to give names (called labels) to addresses. Any word that is not a recognised instruction is assumed to be a label. If the label is before the instruction (or DAT) then it defines the label as representing that address; if it is after the instruction (or DAT) then the address is substituted for the label. The two boxes to the left of the LMC are the input to the assemble function and the intermediate output with the labels converted to the correct numbers.
You can also put comments into the program (with this implementation). Any line starting with // is ignored by the assembler. (I have put mine at the end so the intermediate output lines up with the input but you can put them anywhere in the program.) The assemble function also looks only for an optional initial label, an instruction code and an address for the instruction if it has one, anything after that is ignored. So you can also put comments after instructions. (The // is optional in this case but good practice.) Beware that if you omit an address you will normally get 0, but if you miss out the address and add a comment you will get an error.
The assembler accepts both lower and upper case and for instructions will accept either or a mixture. Note that the case is important for labels, Loop and loop are different labels for example (but not good practice).
In addition to using SELECT (see next paragraph), the CPU can be programmed by entering numbers representing the instructions directly into memory, by typing into or modifying the assembly language area or by preparing a file containing symbolic instructions which can be loaded into the assembly language area. A program called the assembler is then run to convert the assembly language to numbers in memory. (Using a file is similar to how I prepared programs on paper tape in 1970 - except it is easier to correct mistakes in Notepad.) To help you, ASSEMBLE is automatically done whenever you change the assembly language area.
There is a SELECT button which will allow you to select from the following supplied programs:
add | Output the sum of two numbers. Requests input twice. | |
add/subtr | Input three numbers. Output the sum of the first two and the third minus the first. | |
ascii | ASCII stands for American Standard Code for Information Interchange and is the way of encoding characters so they can be stored and manipulated by computers. The original code used the numbers 33 to 126 to represent printable characters and 0-31 and 127 to represent control functions. 32 is used for space and is normally considered a printable character (even though you cannot print it). The only useful control function on the LMC is 10 for newline. This program outputs the numbers 32 to 126 as characters. | |
ascii table | Prints a number, a space and then the corresponding character for numbers 32 to 96. Above 99 the 4 characters per line output limit becomes a problem but you could remove the space and change max to go further. |
To start using this LMC, I suggest:
You can STOP and RUN again at any point. STOP pauses execution; if the flow of execution is not being shown, the current instruction is completed before stopping. At low speeds the pause is instant and you can press STOP again to finish the current instruction. (If you want to abort instantly use RESET.) After a STOP, use RUN or STEP to continue execution.
The STEP button does one instruction only (at a slow speed). You can RESET to go back to the beginning (which is always with Program Counter = 0 on the LMC) or set the Program Counter to any memory address.
You can input into the INPUT box (when the running program requests it) and (when the program is not running) into the individual memory locations, the Program Counter or the Assembly Language area. You cannot alter the Code area or the CPU registers apart from the Program Counter. For memory, the INPUT box and the Program Counter only numbers are accepted.
There is no SAVE capability but you can copy and paste from the Assembly Language area into Notepad (or another plain text editor - I prefer SciTE), save a file, change it with the text editor (if you wish) and use LOAD to get the instructions into the LMC. (Note that LOAD is not available on older browser versions or tablets.)
The OPTIONS button has some useful features:
It is a condition of use that you do not make automated or synchronised attempts to load the software. This overloads the hosting service.
The logs are currently (Oct-Dec 2022) showing cases of about 30 load attempts from the same IP address in two or three seconds. I can only assume this is people using a management system to load a room full of computers at the same time and it is overloading the hosting service for the LMC (which affects all my web sites). I ask you not to do this and get the students to do their own setup (obviously without deliberately synchronising). The average load over the day is insignificant, and I really want people to use my stuff; however I have implemented rate limiting to limit loads per second with automatic retries.
Please do not hit F5 or an equivalent; be patient and let me choose the retry interval based on the current load. Where this fails to work, you will be required to login to use the Simulator or the IP address will be blocked. Please also do not hit F5 more than once a minute during use.
As part of rate limiting and classroom detection an essential cookie "RATELIMIT" is now set. This is not shared with any other site.
© 2014-23 Peter L Higginson (plh256 at hotmail.com)
Original graphics background © Mike Coley (used with permission); I also used his SmallTalk implementation as a starting point. Apart from some of the variable names there is little of that left now. However its help is gratefully acknowledged. The idea for the moving blobs to illustrate the computer's operation came from Romayne Sorhaindo's "CPU Fetch - Decode - Execute Cycle" project on the Computers and Schools web site (computingatschool.org.uk).
I debugged this using Chrome so if you get any problems please check whether they appear in Chrome as well. (I would still be interested to hear about browser specific issues and any use made of the project.)